function  [V]=JCDLGL(X,alpha,beta,mu,r,c,U,S,V,dataset_name)

iternum = 100;
[d,n] = size(X);

L = ones(d,1);
Q = ones(1,n);
error = zeros(iternum, 1);
for i=1:iternum
  
%  Alternatively update V, U ,S and A
   %tic;    
   if i>=2
        oA = A;
	    oQ = Q;
        obj = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
   end
   [A,Q] = UpdateA(U, X, V, Q, alpha, c);
   if i>=2
        Tcost = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
        if  Tcost - obj > 0  
            fprintf('UpdateA: increasesA %f at %d iteration\n',Tcost - obj, i);
            A = oA;
		   Q = oQ;
        end
   end
   
  % if i>=2
  %      oU = U;
  %	    oQ = Q;
  %	    obj = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
  % end
   [U, Q] = UpdateU(A, X, U, Q, c);        %update U
  % if i>=2
  %      Tcost = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
  %     if  Tcost - obj > 0  
  %          fprintf('Update U:increases %f at %d iteration\n',Tcost - obj, i);
  %          U = oU;
  %		   Q = oQ;
  %     end
  % end
   
   if i>=2
      oV = V;
      oL = L;
      obj = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
   end
   %Update V
   [V,L] = UpdateV(A, X, beta/n, alpha/n, mu/d, L, S, r);
   if i>=2
      Tcost = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
	  if Tcost - obj > 0
		fprintf('Update V:increases %f at %d iteration\n',Tcost - obj, i);
         V = oV;
         L = oL;
	  end
    end

   if i>=2
      oS = S;
      obj = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
   end
   %Update S
   [S] = UpdateS(X, V, r);
   if i>=2
      Tcost = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
	  if Tcost - obj > 0
		fprintf('Update S:increases %f at %d iteration\n',Tcost - obj, i);
         S = oS;
	  end
    end
   
      
   %objective function
        error(i) = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d);
        if i > 1 && error(i-1)-error(i) < 0
            fprintf('error(%d): %f, error(%d): %f===%f\n', i - 1, error(i - 1), i, error(i), error(i-1)-error(i)); 
        end
        if i>1 && (error(i-1)-error(i))/error(i-1)<1e-6
            break;
        end
end
	objvalues = error;

%%save convergence
%	foldname = sprintf('../results/convergence');
%	if ~exist(foldname, 'dir')
%    	mkdir(foldname);
%	end
%	filename = sprintf('%s/convergence_%s.mat', foldname, dataset_name);
%	save(filename,'objvalues');

%%save similarity graph
%	foldname = sprintf('../results/simiGraph/%s',dataset_name);
%	if ~exist(foldname, 'dir')
%    	mkdir(foldname);
%	end
%	filename = sprintf('%s/simiGraph_alpha%f_beta%f_mu%f.mat', foldname, alpha, beta, mu);
%	save(filename,'S');
end

function obj = objValue(X, U, A, V, S, alpha, beta, mu, r, n, c, d)
count = 0;
for i = 1:n
	tmp = X(:,i)-U*A(:,i);
	count = count + log(1+sum(tmp.*tmp)/c^2);
end
E1=count/n;
E2=A-V'*X;
tS = S.^r;
Q=(tS+tS')/2;
Ls=diag(sum(Q))-Q;
VX=X'*V;
gvw = trace(VX'*Ls*VX);

clear tS; clear Ds; clear Ls; 
% Compute the objective values
vc = sqrt(sum(V.*V,2));
obj = E1+alpha/n*sum(sum(E2.*E2))+beta/n*gvw+mu/d*sum(vc);
end
